package com.pomty.pombook;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.ContentValues;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Parcelable;
import android.util.Log;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.MenuItem.OnMenuItemClickListener;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.LinearLayout.LayoutParams;

import com.codecarpet.fbconnect.FBLoginButton;
import com.codecarpet.fbconnect.FBPermissionActivity;
import com.codecarpet.fbconnect.FBRequest;
import com.codecarpet.fbconnect.FBSession;
import com.codecarpet.fbconnect.FBLoginButton.FBLoginButtonStyle;
import com.codecarpet.fbconnect.FBRequest.FBRequestDelegate;
import com.codecarpet.fbconnect.FBSession.FBSessionDelegate;
import com.pomty.pombook.gallery.IImage;

public class SharingActivity extends Activity {
	private static final String kApiKey = "771f68771e3374034bdae308adf6aa8b"; // "<YOUR API KEY>";

	// Enter either your API secret or a callback URL (as described in documentation):
    private static final String kApiSecret = "e9f1b67d05851a33ed4ced3cc85b63b0"; // "<YOUR SECRET KEY>";
    private static final String kGetSessionProxy = null; // "<YOUR SESSION CALLBACK)>";
    public static final String PHOTOUPLOADPERMISSION= "photo_upload";
    
     // /////////////////////////////////////////////////////////////////////////////////////////////////
    
    private FBSession mSession;
    private FBLoginButton mLoginButton;
    private Handler mHandler;
    private long sessionId;
    private String sessionName;
    private TextView mFacebookLabel;
    private static final String SAVEDLISTKEY = "ALBUMNAMES";
    private static final String SAVEDNAMEKEY = "SESSIONNAME";
    
    private Button mSendButton;
    private ImageView mCreateAlbum;
    private ImageView mRefreshAlbum;
    private ProgressDialog mProgress;
    private Map<Integer, String> mFBAlbumsIndexAids;
    protected boolean mIsAlbumToAdd = false;
    private Spinner mAlbumSpinner;
    private EditText mCaption;

	private ArrayList<Parcelable> mImageUris;
	private ArrayList<String> mAlbumsList;

		
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		
		mProgress = new ProgressDialog(this);
		mProgress.setTitle(R.string.pleaseWait);
	    
		mHandler = new Handler();
		sessionId = 0;
		
		if (FBSession.getSession() != null)
		{
			mSession = FBSession.getSession();
			mSession.getDelegates().add(new FBSessionDelegateImplem());
		}
		else if (kGetSessionProxy != null) {
            mSession = FBSession.getSessionForApplication_getSessionProxy(kApiKey, kGetSessionProxy, new FBSessionDelegateImplem());
        } else {
            mSession = FBSession.getSessionForApplication_secret(kApiKey, kApiSecret, new FBSessionDelegateImplem());
        }
		
		setContentView(R.layout.sharing);
		
		mFacebookLabel = (TextView) findViewById(R.id.facebookLabel);
        mLoginButton = (FBLoginButton) findViewById(R.id.login);
        mLoginButton.setStyle(FBLoginButtonStyle.FBLoginButtonStyleWide);
		mLoginButton.setSession(mSession);
		
		mCaption = (EditText)findViewById(R.id.caption);
		
		mSendButton = (Button)findViewById(R.id.ButtonSend);
		mSendButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
		        try{
		        	sharePhotoOnFB(mFBAlbumsIndexAids.get(mAlbumSpinner.getSelectedItemPosition()), mCaption.getText().toString());
		        }
		        catch (Exception e)
		        {
		        	Toast.makeText(getApplicationContext(), R.string.photoNotSent, Toast.LENGTH_LONG).show();
		        	e.printStackTrace();
		        }
			}
		});
		mCreateAlbum = (ImageView) findViewById(R.id.ImageAdd);
		mCreateAlbum.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				askUserForInput();
			}
		});
		
		mRefreshAlbum = (ImageView)findViewById(R.id.ImageRefresh);
		mRefreshAlbum.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				updateAlbums();
			}
		});
		
		mFBAlbumsIndexAids = new HashMap<Integer, String>();
		mAlbumSpinner = (Spinner)findViewById(R.id.Spinner01);
		mAlbumsList = new ArrayList<String>();
		
		if (savedInstanceState != null)
		{
			mAlbumsList = savedInstanceState.getStringArrayList(SAVEDLISTKEY);
			setSpinnerAdapter(mAlbumsList);
			
			setSessionName(savedInstanceState.getString(SAVEDNAMEKEY));
		}
		else
			initSpinner();
		
		if (!mSession.isConnected())
			mSession.resume(this);
		else
		{
			queryUserName();
		}
		
		Intent intent = getIntent();
		mImageUris = new ArrayList<Parcelable>();
		
        if (intent.getAction().equals(Intent.ACTION_SEND))
        {
        	mImageUris.add((Uri)intent.getExtras().get(Intent.EXTRA_STREAM));

        }
        else if (intent.getAction().equals("android.intent.action.SEND_MULTIPLE"))
        {
        	mImageUris = (ArrayList<Parcelable>)intent.getExtras().get(Intent.EXTRA_STREAM);
        	mCaption.setVisibility(View.INVISIBLE);
        }
        int min = Math.min(3, mImageUris.size());
        LinearLayout lin = (LinearLayout)findViewById(R.id.linearPhotosToSend);
        ImageView image;
        int width = getWindowManager().getDefaultDisplay().getWidth() / 3;
        LayoutParams params = new LayoutParams(android.view.ViewGroup.LayoutParams.WRAP_CONTENT, 90);
        params.gravity = Gravity.CENTER_HORIZONTAL;
        params.setMargins(1, 0, 1, 0);
        for (int i=0; i< min;i++)
        {
        	image = new ImageView(this);
            image.setLayoutParams(params);
	        image.setImageBitmap(Util.makeBitmap(width, IImage.UNCONSTRAINED, (Uri)mImageUris.get(i), getContentResolver()));
	        lin.addView(image);
        }
        
       	new Thread(new Runnable() {
				
				@Override
				public void run() {
					checkPermissionAndDisplayLabel();
				}
			}).start();
    	
        
	}
	
	
	private void initSpinner(){
		DBHelper dbHelper = new DBHelper(this);
		SQLiteDatabase db = dbHelper.getReadableDatabase();
		Cursor cursor = db.query(DBHelper.TABLEALBUM, new String[] {"ID", "AID", "NAME"},    			
					null, null, null, null, null);
		
		startManagingCursor(cursor);
		int indexName = cursor.getColumnIndex("NAME");
		int indexAid = cursor.getColumnIndex("AID");
		int index = 0;
		mFBAlbumsIndexAids.clear();
		mAlbumsList.clear();
		if (cursor.getCount() != 0)
		{
			try{
	    		cursor.moveToFirst();
	    		String albumID;
	    		do
	        	{
	    			albumID = cursor.getString(indexAid);
	    			mFBAlbumsIndexAids.put(index, albumID);
	    			mAlbumsList.add(cursor.getString(indexName));
	    			index++;
	    		}while (cursor.moveToNext());
			}
			catch(Exception e)
			{
				//Sometimes movetonext crashes when you change the screen orientation
				Log.e("Cursor management",e.getMessage());
			}
		}
		cursor.close();
		db.close();
		
		if (mAlbumsList.size() == 0 && mSession.isConnected())
			updateAlbums();
		else	
		{
			setSpinnerAdapter(mAlbumsList);
			
		}
	}
	
	private void setSpinnerAdapter(List<String> albumsList)
	{
		ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, 
				android.R.layout.simple_spinner_item,
				albumsList);
		adapter.setDropDownViewResource(android.R.layout.simple_dropdown_item_1line);
		
		mAlbumSpinner.setAdapter(adapter);
    }
	
	private void askPermission() {
        Intent intent = new Intent(this, FBPermissionActivity.class);
        intent.putExtra("permissions", new String[]{PHOTOUPLOADPERMISSION});
        intent.putExtra("countryCode", getResources().getConfiguration().locale.getLanguage());
        this.startActivityForResult(intent, Main.PERMISSIONREQUESTCODE );
    }
	
	private void checkPermissionAndDisplayLabel() {
    	if(FBSession.getSession() != null && FBSession.getSession().isConnected())
    	{
	    	String fql = "select " + Main.PHOTOUPLOADPERMISSION + " from permissions where uid == " + String.valueOf(FBSession.getSession().getUid());
			Map<String, String> params = Collections.singletonMap("query", fql);
			FBRequest.requestWithDelegate(new FBHasPermissionRD()).call("facebook.fql.query", params);
    	}
	}
    
	private class FBHasPermissionRD extends FBRequestDelegate {
		@Override
		public void requestDidFailWithError(FBRequest request,
				Throwable error) {
			// TODO Auto-generated method stub
			
			super.requestDidFailWithError(request, error);
		}

		@Override
		public void requestWasCancelled(FBRequest request) {
			// TODO Auto-generated method stub
			super.requestWasCancelled(request);
		}

		@Override
		public void requestDidLoad(FBRequest request, Object result) {
            int hasPermission = 0;
            
            if (result instanceof JSONArray) {
                JSONArray jsonArray = (JSONArray) result;
                try {
                    JSONObject jo = jsonArray.getJSONObject(0);
                    hasPermission = jo.getInt(Main.PHOTOUPLOADPERMISSION);
                    if (hasPermission == 0)
                    {
                        mHandler.post(new Runnable() {
                            public void run() {
                                Toast.makeText(getApplicationContext(), R.string.clickMenuForPermission, Toast.LENGTH_LONG).show();
                            }
                         });
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }
    }
	
    

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
    	if (mSession.isConnected())
		{
    		MenuItem item = menu.add(Menu.NONE, Menu.NONE, Menu.NONE, R.string.permissionPhotoUpload);
    		item.setOnMenuItemClickListener(new OnMenuItemClickListener() {
				
				@Override
				public boolean onMenuItemClick(MenuItem item) {
					checkPermissionAndLaunchActivity();
					return true;
				}
			});
    		item.setIcon(R.drawable.ic_menu_multiselect_gallery);
		}
		return super.onCreateOptionsMenu(menu);
	}

	private void checkPermissionAndLaunchActivity() {
    	String fql = "select " + PHOTOUPLOADPERMISSION + " from permissions where uid == " + String.valueOf(mSession.getUid());
		Map<String, String> params = Collections.singletonMap("query", fql);
		FBRequest.requestWithDelegate(new FBHasPermissionLaunchActivity()).call("facebook.fql.query", params);
	}    
	
   
    public class FBHasPermissionLaunchActivity extends FBRequestDelegate {
		@Override
		public void requestDidFailWithError(FBRequest request,
				Throwable error) {
			// TODO Auto-generated method stub
			
			super.requestDidFailWithError(request, error);
		}

		@Override
		public void requestWasCancelled(FBRequest request) {
			// TODO Auto-generated method stub
			super.requestWasCancelled(request);
		}

		@Override
		public void requestDidLoad(FBRequest request, Object result) {
            int hasPermission = 0;
            
            if (result instanceof JSONArray) {
                JSONArray jsonArray = (JSONArray) result;
                try {
                    JSONObject jo = jsonArray.getJSONObject(0);
                    hasPermission = jo.getInt(PHOTOUPLOADPERMISSION);
                    if (hasPermission == 0)
                    {
                        mHandler.post(new Runnable() {
                            public void run() {
                                askPermission();
                            }
                         });
                    }
                    else
                    {
                    	mHandler.post(new Runnable() {
                            public void run() {
                            	Toast.makeText(getApplicationContext(), R.string.alreadyAllowedPermission, Toast.LENGTH_LONG).show();
                            }
                         });
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }
    }
	
    private class FBSessionDelegateImplem extends FBSessionDelegate {
    	
    	@Override
    	public void sessionDidLogin(FBSession session, Long uid) {
        	queryUserName();
        }

    	@Override
        public void sessionDidLogout(FBSession session) {
            mHandler.post(new Runnable() {
                public void run() {
                	mFacebookLabel.setText(getString(R.string.facebook));
                	mLoginButton.invalidate();
                }});
        }
    }
	
	
    private class FBRequestDelegateImpl extends FBRequestDelegate {
    	@Override
        public void requestDidLoad(FBRequest request, Object result) {
            
            String name = null;
            
            if (result instanceof JSONArray) {
                JSONArray jsonArray = (JSONArray) result;
                try {
                    JSONObject jo = jsonArray.getJSONObject(0);
                    name = jo.getString("name");
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                setSessionName(name);
            }
            
        }
    }
    
    private void setSessionName(String name)
    {
    	if (name != null){
			sessionName = name;
	        mHandler.post(new Runnable() {
	            public void run() {
	            	mFacebookLabel.setText(getString(R.string.loggedInAs) + " " + sessionName);
	            }});
    	}
    }
    
    
    private void queryUserName()
    {
    	sessionId = mSession.getUid();
        
        Thread worker = new Thread(new Runnable() {
    		public void run() {
				String fql = "select uid,name from user where uid == " + sessionId;
				Map<String, String> params = Collections.singletonMap("query", fql);
				
				FBRequest.requestWithDelegate(new FBRequestDelegateImpl()).call("facebook.fql.query", params);
    		}
        });
        worker.start();
    }
    
    private void sharePhotoOnFB(final String albumId, final String caption)
    {
    	final int nbImages = mImageUris.size();
    	final boolean plural = nbImages > 1;
    	if (FBSession.getSession() != null && FBSession.getSession().isConnected())
    	{
			mHandler.post(new Runnable() {
				
				@Override
				public void run() {
					Toast.makeText(getApplicationContext(), plural ? R.string.sendingPhotos : R.string.sendingPhoto, Toast.LENGTH_LONG).show();
				}
			});
			Thread worker = new Thread(new Runnable() {
	    		public void run() {
	    			try
					{
	    				FBRequest _shareRequest = FBRequest.requestWithDelegate(new FBRequestSendPhotoDelegateImpl());
						Map<String, String> parameters = new HashMap<String, String>();
						parameters.put("aid", albumId);
						if (caption != null)
							parameters.put("caption", caption);
						//_shareRequest.call("Photos.upload", parameters, Images.Media.getBitmap(getContentResolver(), mAllImages.getImageAt(mCurrentPosition).fullSizeImageUri()));
						for (int i =0; i < nbImages; i++)
						{
							_shareRequest.call("Photos.upload", parameters, Util.makeBitmap(604, 364816, (Uri)mImageUris.get(i), getContentResolver(), true));
						}
					}
					catch(Exception e)
					{
						e.printStackTrace();
					}
	    		}
	    	});
	        worker.start();
	        finish();
    	}
    	else
    	{
    		mHandler.post(new Runnable() {
				
				@Override
				public void run() {
					Toast.makeText(getApplicationContext(), R.string.toastNotConnected, Toast.LENGTH_LONG).show();
				}
			});
    	}
    }
    
    private void askUserForInput() {
    	AlertDialog.Builder alert = new AlertDialog.Builder(this);  
    	  
    	alert.setTitle(R.string.newAlbum);  
    	alert.setMessage(R.string.albumName);  
    	  
    	// Set an EditText view to get user input   
    	final EditText input = new EditText(this);  
    	alert.setView(input);  
    	  
    	alert.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {  
    	public void onClick(DialogInterface dialog, int whichButton) {   
    	  createAlbumOnFB(input.getText().toString());   
    	  }  
    	});  
    	  
    	alert.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {  
    	  public void onClick(DialogInterface dialog, int whichButton) {  
    	    // Canceled.  
    	  }  
    	});  
    	  
    	alert.show();  
		
	}

	
	private void createAlbumOnFB(final String albumName)
    {
    	if (FBSession.getSession() != null && FBSession.getSession().isConnected())
    	{
    		Thread worker = new Thread(new Runnable() {
	    		public void run() {
	    			mHandler.post(new Runnable() {
						
						

						@Override
						public void run() {
							mProgress.setMessage(getString(R.string.progressCreatingAlbum));
							mProgress.show();
						}
					});
			    	
		    		try
					{
						FBRequest _createAlbum = FBRequest.requestWithDelegate(new FBCreateAlbumDelegateImpl());
						Map<String, String> parameters = new HashMap<String, String>();
						parameters.put("name", albumName);
						_createAlbum.call("Photos.createAlbum", parameters);
					}
					catch(Exception e)
					{
						Log.e("create request", e.getMessage());
					}
	    		}
    		});
    		worker.start();
    	}
    	else
    	{
    		mHandler.post(new Runnable() {
				
				@Override
				public void run() {
					Toast.makeText(getApplicationContext(), R.string.toastNotConnected, Toast.LENGTH_LONG);
				}
			});
    	}
    }
	
	
	private class FBRequestSendPhotoDelegateImpl extends FBRequestDelegate {

		@Override
		public void requestDidFailWithError(FBRequest request,
				Throwable error) {
			mHandler.post(new Runnable() {
				
				@Override
				public void run() {
					Toast.makeText(getApplicationContext(), R.string.photoNotSent, Toast.LENGTH_LONG).show();
					
				}
			});
		}

		@Override
		public void requestWasCancelled(FBRequest request) {
			mHandler.post(new Runnable() {
				
				@Override
				public void run() {
					Toast.makeText(getApplicationContext(), R.string.photoNotSent, Toast.LENGTH_LONG).show();
					
				}
			});
		}

		public void requestDidLoad(FBRequest request, Object result) {
			mHandler.post(new Runnable() {
				
				@Override
				public void run() {
					Toast.makeText(getApplicationContext(), R.string.photoSent, Toast.LENGTH_LONG).show();
				}
			});
        }
    }
	
	private void updateAlbums()
	{
    	if (FBSession.getSession() != null && FBSession.getSession().isConnected())
    	{
			Thread worker = new Thread(new Runnable() {
	    		public void run() {
	    			
	    			mHandler.post(new Runnable() {
	    				public void run() {
	    					mProgress.setMessage(getString(R.string.loadAlbumsDialogMessage));
	    					mProgress.show();
		    	}});
		        
		    	FBRequest _albumRequest = FBRequest.requestWithDelegate(new FBRequestGetAlbumsDelegateImpl());
		        Map<String, String> parameters = new HashMap<String, String>();
		    	parameters.put("uid", String.valueOf(sessionId));
		    	_albumRequest.call("Photos.getAlbums", parameters);
	            }
	        });
	    	worker.start();
    	}
    	else
    	{
    		Toast.makeText(this, R.string.toastNotConnected, Toast.LENGTH_LONG).show();
    	}
	}
	
	private class FBRequestGetAlbumsDelegateImpl extends FBRequestDelegate {
    	@Override
        public void requestDidLoad(FBRequest request, Object result) {
        	
        	JSONArray array = (JSONArray)result;
        	HashMap<String, Object> map = new HashMap<String, Object>();
        	int nbAlbumsTotal = array.length();
        	JSONObject o;
        	Iterator ji;
        	mFBAlbumsIndexAids.clear();
        	mAlbumsList.clear();
        	for (int i = 0; i < nbAlbumsTotal; i++)
        	{
        		
        		map.clear();
        		
        		try {
					o = (JSONObject) array.get(i);
					ji = o.keys();
					while (ji.hasNext()) {
						String key = (String) ji.next();
					    Object val = o.get(key);
				        map.put(key, val);
					}
					       
				} catch (JSONException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
				mAlbumsList.add((String)map.get("name"));
				mFBAlbumsIndexAids.put(i, (String)map.get("aid"));
				
            	
        	}
        	mHandler.post(new Runnable() {
                public void run() {
                	setSpinnerAdapter(mAlbumsList);
                	mProgress.hide();
	            }
            });
        	return;
        }
        
        @Override
		public void requestDidFailWithError(FBRequest request,
				Throwable error) {
			mHandler.post(new Runnable() {
				public void run() {
					mProgress.hide();
					Toast.makeText(getApplicationContext(), R.string.error, Toast.LENGTH_LONG).show();
  				}});
			super.requestDidFailWithError(request, error);
		}

		@Override
		public void requestWasCancelled(FBRequest request) {
			mHandler.post(new Runnable() {
				public void run() {
					mProgress.hide();
					Toast.makeText(getApplicationContext(), R.string.error, Toast.LENGTH_LONG).show();
  				}});
			super.requestWasCancelled(request);
		}
    }
    
    
    private class FBCreateAlbumDelegateImpl extends FBRequestDelegate {



		@Override
		public void requestDidFailWithError(FBRequest request,
				Throwable error) {
			mHandler.post(new Runnable() {
				
				@Override
				public void run() {
					mProgress.hide();
					Toast.makeText(getApplicationContext(), R.string.albumNotCreated, Toast.LENGTH_LONG).show();
					
				}
			});
		}

		@Override
		public void requestWasCancelled(FBRequest request) {
			mHandler.post(new Runnable() {
				
				@Override
				public void run() {
					mProgress.hide();
					Toast.makeText(getApplicationContext(), R.string.albumNotCreated, Toast.LENGTH_LONG).show();
					
				}
			});
		}

		public void requestDidLoad(FBRequest request, Object result) {
			mHandler.post(new Runnable() {
				
				@Override
				public void run() {
					//mProgress.setMessage(getString(R.string.progressSendingPhoto));
					mProgress.hide();
				}
			});
			
			String aid = null;
			String name = null;
            if (result instanceof JSONArray) {
                JSONArray jsonArray = (JSONArray) result;
                try {
                    JSONObject jo = jsonArray.getJSONObject(0);
                    aid = jo.getString("aid");
                } catch (JSONException e) {
                    e.printStackTrace();
                }
				//sharePhotoOnFB(aid, mCurrentPosition);
            }
            if (result instanceof JSONObject) {
            	JSONObject jsonObj = (JSONObject) result;
            	try {
            		aid = jsonObj.getString("aid");
            		name = jsonObj.getString("name");
            		mIsAlbumToAdd = true;
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            	//sharePhotoOnFB(aid, mCurrentPosition);
            	
            }
            
            DBHelper dbHelper = new DBHelper(getApplicationContext());
        	SQLiteDatabase db = dbHelper.getWritableDatabase();
        	ContentValues values = new ContentValues();
        	db.beginTransaction();
        	try{
	        	values.put("AID", aid);
		        values.put("NAME", name);
		        values.put("COVERID", 0);
		        db.insert("ALBUM", "NAME", values);
		        db.setTransactionSuccessful();
	        }
	        finally{
	        	db.endTransaction();
	        }
	        db.close();
	        
	        mHandler.post(new Runnable() {
				
				@Override
				public void run() {
					initSpinner();
				}
			});
        }
    }


	@Override
	protected void onSaveInstanceState(Bundle outState) {
		// TODO Auto-generated method stub
		super.onSaveInstanceState(outState);
		outState.putStringArrayList(SAVEDLISTKEY, mAlbumsList);
		outState.putString(SAVEDNAMEKEY, sessionName);
	}
}